<template>
  <div class="h-full w-full bg-gray-50 flex flex-col">
    <!-- 页面标题和统计摘要 - 根据扫描状态显示 -->
    <div class="bg-white border-b border-gray-200 px-6 py-4 flex-shrink-0">
      <div class="flex items-center justify-between">
        <!-- 页面标题 -->
        <div class="flex items-center space-x-3">
          <div class="w-8 h-8 bg-green-100 rounded-full flex items-center justify-center">
            <svg class="w-4 h-4 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
            </svg>
          </div>
          <div>
            <h2 class="text-lg font-semibold text-gray-900">{{ hasScanResults ? '扫描完成' : '扫描结果' }}</h2>
            <p class="text-sm text-gray-600">{{ hasScanResults ? '发现重复文件，请查看详细结果' : '暂无扫描结果，请先进行文件扫描' }}</p>
          </div>
        </div>

        <!-- 统计摘要 - 根据扫描状态显示 -->
        <div class="flex space-x-4">
          <div class="bg-blue-50 rounded-lg px-4 py-2 border border-blue-100 text-center">
            <div class="text-lg font-bold text-blue-600">{{ totalFiles }}</div>
            <div class="text-sm text-blue-700">总文件数</div>
          </div>
          <div class="bg-green-50 rounded-lg px-4 py-2 border border-green-100 text-center">
            <div class="text-lg font-bold text-green-600">{{ duplicateGroups }}</div>
            <div class="text-sm text-green-700">重复组数</div>
          </div>
          <div class="bg-purple-50 rounded-lg px-4 py-2 border border-purple-100 text-center">
            <div class="text-lg font-bold text-purple-600">{{ duplicateFiles }}</div>
            <div class="text-sm text-purple-700">重复文件数</div>
          </div>
          <div class="bg-orange-50 rounded-lg px-4 py-2 border border-orange-100 text-center">
            <div class="text-lg font-bold text-orange-600">{{ totalSavedSpace }}</div>
            <div class="text-sm text-orange-700">可节省空间</div>
          </div>
        </div>
      </div>
    </div>

    <!-- 主要内容区域 - 左右布局，左侧文件列表可滚动 -->
    <div class="flex-1 flex min-h-0 pb-24">
      <!-- 左侧：重复文件列表 - 可滚动，增加间距 -->
      <div class="flex-1 p-6 min-w-0">
        <div class="h-full flex flex-col">
          <div class="flex items-center justify-between mb-4 flex-shrink-0">
            <h3 class="text-lg font-semibold text-gray-900">重复文件详情</h3>
            <div class="flex items-center space-x-4">
              <div class="text-sm text-gray-500">
                共 {{ duplicateGroups }} 组，{{ duplicateFiles }} 个重复文件
              </div>
              
              <!-- 排序选项 -->
              <div class="flex items-center space-x-2">
                <span class="text-sm text-gray-600">排序:</span>
                <select 
                  v-model="sortOption" 
                  @change="applySorting"
                  class="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                  data-allow-selection="true"
                >
                  <option value="default">默认顺序</option>
                  <option value="groupSize">按组大小</option>
                  <option value="fileSize">按文件大小</option>
                  <option value="fileName">按文件名</option>
                  <option value="filePath">按文件路径</option>
                  <option value="modifiedDate">按修改日期</option>
                  <option value="savedSpace">按可节省空间</option>
                </select>
                
                <button 
                  @click="toggleSortDirection"
                  class="px-2 py-2 border border-gray-300 rounded-lg text-sm hover:bg-gray-50 transition-colors"
                  :title="sortDirection === 'asc' ? '升序排列' : '降序排列'"
                >
                  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path v-if="sortDirection === 'asc'" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12"></path>
                    <path v-else stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12"></path>
                  </svg>
                </button>
              </div>
              
              <!-- 刷新按钮 -->
              <button 
                @click="refreshResults"
                class="px-3 py-2 bg-blue-500 hover:bg-blue-600 text-white text-sm rounded-lg transition-colors flex items-center space-x-2"
                title="刷新扫描结果，清除已删除的文件"
              >
                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
                </svg>
                <span>刷新结果</span>
              </button>
            </div>
          </div>
          
          <!-- 文件列表区域 - 可滚动，增加间距 -->
          <div 
            class="flex-1 overflow-y-auto"
            data-context-menu-id="file-list"
            @contextmenu.prevent="showListContextMenu($event)"
          >
            <!-- 视图切换按钮 -->
            <div class="mb-4 flex items-center gap-4">
              <div class="flex items-center gap-2">
                <span class="text-sm text-gray-600">视图模式:</span>
                <button 
                  @click="viewMode = 'list'"
                  :class="[
                    'px-3 py-1.5 text-sm rounded-lg transition-colors',
                    viewMode === 'list' 
                      ? 'bg-blue-500 text-white' 
                      : 'bg-gray-200 text-gray-700 hover:bg-gray-300'
                  ]"
                >
                  列表
                </button>
                <button 
                  @click="viewMode = 'grid'"
                  :class="[
                    'px-3 py-1.5 text-sm rounded-lg transition-colors',
                    viewMode === 'grid' 
                      ? 'bg-blue-500 text-white' 
                      : 'bg-gray-200 text-gray-700 hover:bg-gray-300'
                  ]"
                >
                  缩略图
                </button>
                <button 
                  @click="viewMode = 'cluster'"
                  :class="[
                    'px-3 py-1.5 text-sm rounded-lg transition-colors',
                    viewMode === 'cluster' 
                      ? 'bg-blue-500 text-white' 
                      : 'bg-gray-200 text-gray-700 hover:bg-gray-300'
                  ]"
                >
                  聚类
                </button>
              </div>
            </div>

            <!-- 缩略图网格视图 -->
            <ThumbnailGrid 
              v-if="viewMode === 'grid'"
              :groups="thumbnailGroups"
              :container-height="600"
              @file-select="handleThumbnailFileSelect"
              @update:groups="updateThumbnailGroups"
            />

            <!-- 聚类视图 -->
            <SimilarityClusterView 
              v-else-if="viewMode === 'cluster'"
              :duplicate-groups="duplicateGroupsList"
              @update-groups="handleClusterUpdate"
            />

            <!-- 列表视图 -->
            <div v-else>
              <div v-for="(group, groupIndex) in (sortedGroups.length > 0 ? sortedGroups : duplicateGroupsList)" :key="groupIndex" class="bg-white rounded-lg border border-gray-200 p-4 mb-4 shadow-sm">
              <div 
                class="flex items-center justify-between mb-3"
                :data-context-menu-id="`group-${groupIndex}`"
                @contextmenu.prevent="showGroupContextMenu($event, groupIndex)"
              >
                <div class="flex items-center space-x-3">
                  <span class="text-base font-medium text-gray-900">组 {{ groupIndex + 1 }}</span>
                  <span class="px-2 py-1 bg-blue-100 text-blue-800 text-sm rounded">{{ group.files.length }} 个文件</span>
                  <span class="px-2 py-1 bg-green-100 text-green-800 text-sm rounded">{{ formatFileSize(group.size) }}</span>
                  <span v-if="getGroupSavedSpace(group) > 0" class="px-2 py-1 bg-orange-100 text-orange-800 text-sm rounded">
                    可节省 {{ formatFileSize(getGroupSavedSpace(group)) }}
                  </span>
                </div>
                <div class="flex space-x-2">
                  <button 
                    @click="selectAllInGroup(groupIndex)"
                    class="px-3 py-1.5 bg-blue-500 hover:bg-blue-600 text-white text-sm rounded-lg transition-colors"
                  >
                    全选
                  </button>
                  <button 
                    @click="deselectAllInGroup(groupIndex)"
                    class="px-3 py-1.5 bg-gray-500 hover:bg-gray-600 text-white text-sm rounded-lg transition-colors"
                  >
                    取消全选
                  </button>
                </div>
              </div>
              
              <div class="space-y-2">
                <div 
                  v-for="(file, fileIndex) in group.files" 
                  :key="fileIndex" 
                  class="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg border border-gray-200 hover:bg-gray-100 transition-colors"
                  :data-context-menu-id="`file-${groupIndex}-${fileIndex}`"
                  @contextmenu.prevent="showFileContextMenu($event, groupIndex, fileIndex)"
                >
                  <input 
                    type="checkbox" 
                    :id="`file-${groupIndex}-${fileIndex}`"
                    v-model="file.selected"
                    class="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
                    data-allow-selection="true"
                  >
                  <!-- 缩略图 -->
                  <div class="w-16 h-16 bg-gray-100 rounded flex items-center justify-center flex-shrink-0 overflow-hidden">
                    <img 
                      v-if="file.thumbnailData"
                      :src="`data:image/webp;base64,${file.thumbnailData}`"
                      :alt="file.name"
                      class="w-full h-full object-cover"
                      @error="handleThumbnailError(file)"
                    />
                    <div v-else-if="file.thumbnailLoading" class="w-full h-full flex items-center justify-center">
                      <div class="animate-spin rounded-full h-4 w-4 border-2 border-blue-500 border-t-transparent"></div>
                    </div>
                    <svg v-else class="w-8 h-8 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
                    </svg>
                  </div>
                  
                  <label :for="`file-${groupIndex}-${fileIndex}`" class="flex-1 cursor-pointer">
                    <div class="flex items-center space-x-3">
                      <div class="flex-1 min-w-0">
                        <div class="font-medium text-gray-900 truncate text-sm">{{ file.name }}</div>
                        <div class="text-sm text-gray-500 truncate">{{ file.path }}</div>
                      </div>
                      <div class="text-right flex-shrink-0">
                        <div class="text-sm font-medium text-gray-900">{{ formatFileSize(file.size) }}</div>
                        <div class="text-sm text-gray-500">{{ formatDate(file.modified) }}</div>
                      </div>
                    </div>
                  </label>
                  <!-- 预览按钮 -->
                  <button 
                    v-if="isPreviewableFile(file.name)"
                    @click="previewFile(groupIndex, fileIndex)"
                    class="px-2 py-1 bg-blue-100 hover:bg-blue-200 text-blue-700 text-xs rounded transition-colors flex-shrink-0"
                    title="预览文件"
                  >
                    <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
                    </svg>
                  </button>
                  
                  <!-- 打开文件位置按钮 -->
                  <button 
                    @click="openFileLocation(file.path)"
                    class="px-2 py-1 bg-green-100 hover:bg-green-200 text-green-700 text-xs rounded transition-colors flex-shrink-0"
                    title="在文件管理器中打开文件所在目录"
                  >
                    <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2H5a2 2 0 00-2-2z"></path>
                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5a2 2 0 012-2h2a2 2 0 012 2v2H8V5z"></path>
                    </svg>
                  </button>
                </div>
              </div>
            </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 右侧：选择助手 - 手风琴折叠布局，内部滚动条 -->
      <div class="w-96 bg-white border-l border-gray-200 p-4 flex-shrink-0">
        <div class="h-full flex flex-col">
          <!-- 选择助手内容区域 - 手风琴折叠布局，内部滚动条 -->
          <div class="flex-1 overflow-y-auto">
            <div class="space-y-2">
              <!-- 选择规则 - 手风琴项，自适应高度 -->
              <div class="border border-gray-200 rounded-lg overflow-hidden">
                <button 
                  @click="toggleAccordion('rules')"
                  class="w-full px-3 py-2 bg-gray-50 hover:bg-gray-100 flex items-center justify-between text-left transition-colors"
                >
                  <span class="font-medium text-gray-900">选择规则</span>
                  <svg 
                    class="w-5 h-5 text-gray-500 transition-transform"
                    :class="{ 'rotate-180': accordionOpen.rules }"
                    fill="none" 
                    stroke="currentColor" 
                    viewBox="0 0 24 24"
                  >
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
                  </svg>
                </button>
                <div v-show="accordionOpen.rules" class="border-t border-gray-200">
                  <div class="p-3">
                    <SelectionRules @apply-rules="applyRetentionRules" />
                  </div>
                </div>
              </div>
              
              <!-- 文本模式选择 - 手风琴项，自适应高度 -->
              <div class="border border-gray-200 rounded-lg overflow-hidden">
                <button 
                  @click="toggleAccordion('text')"
                  class="w-full px-3 py-2 bg-gray-50 hover:bg-gray-100 flex items-center justify-between text-left transition-colors"
                >
                  <span class="font-medium text-gray-900">按文本模式选择</span>
                  <svg 
                    class="w-5 h-5 text-gray-500 transition-transform"
                    :class="{ 'rotate-180': accordionOpen.text }"
                    fill="none" 
                    stroke="currentColor" 
                    viewBox="0 0 24 24"
                  >
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
                  </svg>
                </button>
                <div v-show="accordionOpen.text" class="border-t border-gray-200">
                  <div class="p-3">
                    <TextModeSelection @mark-files="handleTextModeMarking" />
                  </div>
                </div>
              </div>
              
              <!-- 目录位置选择 - 手风琴项，自适应高度 -->
              <div class="border border-gray-200 rounded-lg overflow-hidden">
                <button 
                  @click="toggleAccordion('location')"
                  class="w-full px-3 py-2 bg-gray-50 hover:bg-gray-100 flex items-center justify-between text-left transition-colors"
                >
                  <span class="font-medium text-gray-900">按目录位置选择</span>
                  <svg 
                    class="w-5 h-5 text-gray-500 transition-transform"
                    :class="{ 'rotate-180': accordionOpen.location }"
                    fill="none" 
                    stroke="currentColor" 
                    viewBox="0 0 24 24"
                  >
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
                  </svg>
                </button>
                <div v-show="accordionOpen.location" class="border-t border-gray-200">
                  <div class="p-3">
                    <LocationSelection @mark-location-files="handleLocationMarking" />
                  </div>
                </div>
              </div>
              
              <!-- 操作按钮 - 紧凑布局 -->
              <div class="pt-2">
                <SelectionActions 
                  :selected-count="selectedCount"
                  :duplicate-count="duplicateFiles"
                  :saved-space="actualSavedSpace"
                  @unmark-all="unmarkAll"
                  @invert-marks="invertAllMarks"
                />
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 底部操作按钮 - 始终显示，固定位置 -->
    <div class="bg-white border-t border-gray-200 px-6 py-4 flex-shrink-0 fixed bottom-0 left-0 right-0 z-20">
      <div class="flex items-center justify-between">
        <div class="flex items-center space-x-4">
          <span class="text-sm text-gray-600">
            已选择 <span class="font-semibold text-blue-600">{{ selectedCount }}</span> 个文件，
            可节省 <span class="font-semibold text-green-600">{{ actualSavedSpace }}</span> 空间
          </span>
        </div>
        
        <div class="flex space-x-3">
          <button 
            @click="selectAllDuplicates"
            class="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white text-sm rounded-lg transition-colors"
          >
            全选所有重复文件
          </button>
          
          <button 
            @click="showDeleteConfirmDialog"
            :disabled="selectedCount === 0"
            :class="[
              'px-4 py-2 text-sm rounded-lg transition-colors',
              selectedCount > 0
                ? 'bg-red-500 hover:bg-red-600 text-white'
                : 'bg-gray-300 text-gray-500 cursor-not-allowed'
            ]"
          >
            删除选中文件
          </button>
        </div>
      </div>
    </div>

    <!-- 右键菜单组件 -->
    <div 
      v-if="contextMenu.visible"
      class="fixed z-50 bg-white border border-gray-200 rounded-lg shadow-lg py-1 min-w-48"
      :style="{ left: contextMenu.x + 'px', top: contextMenu.y + 'px' }"
      @click="hideContextMenu"
      data-allow-selection="true"
    >
      <!-- 文件右键菜单 -->
      <template v-if="contextMenu.target?.type === 'file'">
        <div class="px-4 py-2 text-sm font-medium text-gray-700 border-b border-gray-100">
          文件操作
        </div>
        <button 
          @click="handleContextMenuAction('select')"
          class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center space-x-2"
          data-allow-selection="true"
        >
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
          </svg>
          <span>选择文件</span>
        </button>
        <button 
          @click="handleContextMenuAction('deselect')"
          class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center space-x-2"
          data-allow-selection="true"
        >
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
          </svg>
          <span>取消选择</span>
        </button>
        <button 
          v-if="isPreviewableFile(contextMenu.target?.fileIndex !== undefined ? duplicateGroupsList[contextMenu.target.groupIndex!]?.files[contextMenu.target.fileIndex]?.name : '')"
          @click="handleContextMenuAction('preview')"
          class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center space-x-2"
        >
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
          </svg>
          <span>预览文件</span>
        </button>
        <button 
          @click="handleContextMenuAction('open_location')"
          class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center space-x-2"
        >
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2H5a2 2 0 00-2-2z"></path>
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5a2 2 0 012-2h2a2 2 0 012 2v2H8V5z"></path>
          </svg>
          <span>打开文件位置</span>
        </button>
        <div class="border-t border-gray-100 my-1"></div>
        <button 
          @click="handleContextMenuAction('delete')"
          class="w-full px-4 py-2 text-left text-sm text-red-600 hover:bg-red-50 flex items-center space-x-2"
        >
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
          </svg>
          <span>删除文件</span>
        </button>
      </template>

      <!-- 组右键菜单 -->
      <template v-else-if="contextMenu.target?.type === 'group'">
        <div class="px-4 py-2 text-sm font-medium text-gray-700 border-b border-gray-100">
          组操作
        </div>
        <button 
          @click="handleContextMenuAction('select')"
          class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center space-x-2"
        >
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
          </svg>
          <span>选择组内所有文件</span>
        </button>
        <button 
          @click="handleContextMenuAction('deselect')"
          class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center space-x-2"
        >
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
          </svg>
          <span>取消选择组内所有文件</span>
        </button>
        <div class="border-t border-gray-100 my-1"></div>
        <button 
          @click="handleContextMenuAction('delete')"
          class="w-full px-4 py-2 text-left text-sm text-red-600 hover:bg-red-50 flex items-center space-x-2"
        >
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
          </svg>
          <span>删除组内所有重复文件</span>
        </button>
      </template>

      <!-- 列表右键菜单 -->
      <template v-else-if="contextMenu.target?.type === 'list'">
        <div class="px-4 py-2 text-sm font-medium text-gray-700 border-b border-gray-100">
          列表操作
        </div>
        <button 
          @click="handleContextMenuAction('select_all')"
          class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center space-x-2"
        >
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
          </svg>
          <span>选择所有文件</span>
        </button>
        <button 
          @click="handleContextMenuAction('deselect_all')"
          class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center space-x-2"
        >
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
          </svg>
          <span>取消选择所有文件</span>
        </button>
        <div class="border-t border-gray-100 my-1"></div>
        <button 
          @click="handleContextMenuAction('refresh')"
          class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center space-x-2"
        >
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
          </svg>
          <span>刷新结果</span>
        </button>
      </template>
    </div>

    <!-- 媒体预览组件 -->
    <MediaPreview
      v-if="showPreview"
      :is-visible="showPreview"
      :current-group="currentPreviewGroup"
      :current-file-index="currentPreviewFileIndex"
      @close="closePreview"
      @update-selection="updateFileSelection"
      @navigate-file="navigateToFile"
    />

    <!-- 删除确认模态框 -->
    <div v-if="showDeleteConfirm" class="modal-overlay" @click="cancelDelete">
      <div class="modal-content max-w-md w-full mx-4" @click.stop>
        <div class="p-6">
          <div class="text-center mb-6">
            <div class="mx-auto w-16 h-16 bg-red-100 rounded-full flex items-center justify-center mb-4">
              <svg class="w-8 h-8 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1-1H9a1 1 0 00-1 1v3M4 7h16"></path>
              </svg>
            </div>
            <h3 class="text-lg font-semibold text-gray-900 mb-2">确认删除</h3>
            <p class="text-sm text-gray-600">
              确定要删除 <span class="font-semibold text-red-600">{{ selectedCount }}</span> 个选中的文件吗？<br>
              此操作不可撤销！
            </p>
          </div>

          <!-- 删除选项 -->
          <div class="space-y-4 mb-6">
            <label class="flex items-center space-x-3">
              <input 
                type="checkbox" 
                v-model="deleteOptions.moveToRecycleBin" 
                class="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
              >
              <span class="text-sm text-gray-700">移动到回收站</span>
            </label>
            
            <label class="flex items-center space-x-2">
              <input 
                type="checkbox" 
                v-model="deleteOptions.cleanEmptyFolders" 
                class="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
              >
              <span class="text-sm text-gray-700">清理空文件夹</span>
            </label>
          </div>

          <!-- 操作按钮 -->
          <div class="flex space-x-3">
            <button 
              @click="cancelDelete" 
              class="flex-1 px-4 py-2 bg-gray-500 hover:bg-gray-600 text-white font-medium rounded-lg transition-colors"
            >
              取消
            </button>
            <button 
              @click="confirmDelete" 
              class="flex-1 px-4 py-2 bg-red-600 hover:bg-red-700 text-white font-medium rounded-lg transition-colors"
            >
              确定删除
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch, inject, nextTick } from 'vue'
import { invoke } from '@tauri-apps/api/tauri'
import SelectionRules from './SelectionRules.vue'
import SelectionActions from './SelectionActions.vue'
import TextModeSelection from './TextModeSelection.vue'
import LocationSelection from './LocationSelection.vue'
import MediaPreview from './MediaPreview.vue'
import ThumbnailGrid from './ThumbnailGrid.vue'
import SimilarityClusterView from './SimilarityClusterView.vue'

// 定义props
interface FileInfo {
  name: string
  path: string
  size: number
  modified: Date
  selected: boolean
  thumbnailData?: string
  thumbnailLoading?: boolean
  thumbnailError?: boolean
}

interface DuplicateGroup {
  files: FileInfo[]
  size: number
}

interface Props {
  totalFiles: number
  duplicateGroups: number
  duplicateFiles: number
  savedSpace: string
  duplicateGroupsList: DuplicateGroup[]
}

const props = defineProps<Props>()

// 注入全局右键菜单管理函数
const registerContextMenu = inject('registerContextMenu') as (elementId: string) => void
const unregisterContextMenu = inject('unregisterContextMenu') as (elementId: string) => void

// 定义emits
const emit = defineEmits<{
  navigate: [view: string]
  'update-groups': [groups: DuplicateGroup[]]
}>()

// 计算属性
const selectedCount = computed(() => {
  return props.duplicateGroupsList.reduce((total, group) => {
    return total + group.files.filter(file => file.selected).length
  }, 0)
})

// 计算总的可节省空间（所有重复文件）
const totalSavedSpace = computed(() => {
  let totalSaved = 0
  
  props.duplicateGroupsList.forEach(group => {
    if (group.files.length > 1) {
      // 每组中除了第一个文件外，其他都是重复的，可以删除
      // 第一个文件保留，其他文件的空间可以节省
      const filesToDelete = group.files.slice(1)
      filesToDelete.forEach(file => {
        totalSaved += file.size
      })
    }
  })
  
  return formatFileSize(totalSaved)
})

// 排序相关状态
const sortOption = ref('default')
const sortDirection = ref<'asc' | 'desc'>('desc')
const sortedGroups = ref<DuplicateGroup[]>([])

// 计算已选择文件的可节省空间
const actualSavedSpace = computed(() => {
  let totalSaved = 0
  let debugInfo: string[] = []
  
  props.duplicateGroupsList.forEach((group, groupIndex) => {
    const selectedFiles = group.files.filter(file => file.selected)
    if (selectedFiles.length > 0) {
      let groupSaved = 0
      if (selectedFiles.length > 1) {
        // 选择了多个文件，删除除第一个外的所有文件
        const filesToDelete = selectedFiles.slice(1)
        filesToDelete.forEach(file => {
          groupSaved += file.size
        })
      } else {
        // 只选择了一个文件，这个文件本身就可以删除（因为它是重复的）
        groupSaved += selectedFiles[0].size
      }
      totalSaved += groupSaved
      
      debugInfo.push(`组${groupIndex + 1}: 选择${selectedFiles.length}个文件, 可节省${formatFileSize(groupSaved)}`)
    }
  })
  
  // 调试信息
  if (debugInfo.length > 0) {
    console.log('空间节省计算详情:', debugInfo)
    console.log('总节省空间:', formatFileSize(totalSaved))
  }
  
  return formatFileSize(totalSaved)
})

// 判断是否有扫描结果
const hasScanResults = computed(() => {
  return props.duplicateGroupsList.length > 0 && props.totalFiles > 0
})

// 计算实际重复文件数（总的重复文件数，不是已选择的）
// const actualDuplicateFiles = computed(() => {
//   return props.duplicateGroupsList.reduce((total, group) => {
//     // 每组中除了第一个文件外，其他都是重复的
//     if (group.files.length > 1) {
//       total += group.files.length - 1
//     }
//     return total
//   }, 0)
// })

// 预览相关变量
const showPreview = ref(false)
const currentPreviewGroup = ref<DuplicateGroup | undefined>(undefined)
const currentPreviewFileIndex = ref<number>(0)

// 删除确认相关变量
const showDeleteConfirm = ref(false)
const deleteOptions = ref({
  moveToRecycleBin: true,  // 默认选中：移动到回收站
  cleanEmptyFolders: true   // 默认选中：清理空文件夹
})

// 视图模式相关
const viewMode = ref<'list' | 'grid' | 'cluster'>('list')

// 缩略图网格数据
const thumbnailGroups = computed(() => {
  return props.duplicateGroupsList.map((group, index) => ({
    id: `group_${index}`,
    files: group.files,
    totalSize: group.files.reduce((sum, file) => sum + file.size, 0),
    isExpanded: false // 默认折叠
  }))
})



// 工具函数
const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const formatDate = (date: Date): string => {
  return date.toLocaleDateString('zh-CN')
}

// 操作方法
const selectAllInGroup = (groupIndex: number) => {
  props.duplicateGroupsList[groupIndex].files.forEach(file => {
    file.selected = true
  })
}

const deselectAllInGroup = (groupIndex: number) => {
  props.duplicateGroupsList[groupIndex].files.forEach(file => {
    file.selected = false
  })
}

const selectAllDuplicates = () => {
  props.duplicateGroupsList.forEach(group => {
    group.files.forEach(file => {
      file.selected = true
    })
  })
}

const showDeleteConfirmDialog = () => {
  if (selectedCount.value === 0) {
    console.log('没有选中的文件')
    return
  }
  
  // 显示删除确认模态框
  showDeleteConfirm.value = true
}

// 取消删除
const cancelDelete = () => {
  showDeleteConfirm.value = false
}

// 确认删除
const confirmDelete = async () => {
  try {
    console.log('开始删除选中的文件...')
    console.log('删除选项:', deleteOptions.value)
    
    // 收集所有要删除的文件路径
    const filesToDelete: string[] = []
    
    props.duplicateGroupsList.forEach(group => {
      const selectedFiles = group.files.filter(file => file.selected)
      if (selectedFiles.length > 1) {
        // 如果选择了多个文件，删除除第一个外的所有文件
        const filesToDeleteInGroup = selectedFiles.slice(1)
        filesToDeleteInGroup.forEach(file => {
          filesToDelete.push(file.path)
        })
      } else if (selectedFiles.length === 1) {
        // 如果只选择了一个文件，也删除它（因为它是重复的）
        filesToDelete.push(selectedFiles[0].path)
      }
    })
    
    console.log('要删除的文件数量:', filesToDelete.length)
    console.log('要删除的文件:', filesToDelete)
    
    // 调用后端删除文件
    let successCount = 0
    let failedFiles: string[] = []
    
    for (const filePath of filesToDelete) {
      try {
        if (deleteOptions.value.moveToRecycleBin) {
          // 移动到回收站
          const result = await invoke('move_to_recycle_bin', { filePath })
          console.log('移动到回收站成功:', filePath, result)
          successCount++
        } else {
          // 直接删除
          const result = await invoke('delete_file', { filePath })
          console.log('删除文件成功:', filePath, result)
          successCount++
        }
      } catch (error) {
        console.error('删除文件失败:', filePath, error)
        failedFiles.push(filePath)
      }
    }
    
    // 如果选择了清理空文件夹，调用后端清理
    if (deleteOptions.value.cleanEmptyFolders) {
      try {
        const result = await invoke('clean_empty_folders', { 
          parentPaths: [...new Set(filesToDelete.map(path => 
            path.substring(0, path.lastIndexOf('\\'))
          ))]
        })
        console.log('清理空文件夹结果:', result)
      } catch (error) {
        console.error('清理空文件夹失败:', error)
      }
    }
    
    // 从重复组中移除已删除的文件（只移除成功删除的）
    const updatedGroups = props.duplicateGroupsList.map(group => {
      // 只保留没有成功删除的文件
      const remainingFiles = group.files.filter(file => {
        // 如果文件在要删除的列表中，但不在失败列表中，说明删除成功了，应该移除
        if (filesToDelete.includes(file.path) && !failedFiles.includes(file.path)) {
          return false // 删除成功，移除
        }
        return true // 保留其他文件
      })
      return {
        ...group,
        files: remainingFiles
      }
    }).filter(group => group.files.length > 1) // 移除空的组和只剩一个文件的组（不再是重复文件组）
    
    // 发出事件通知父组件更新数据
    emit('update-groups', updatedGroups)
    
    console.log('文件删除完成，剩余组数:', updatedGroups.length)
    
    // 关闭确认模态框
    showDeleteConfirm.value = false
    
    // 根据删除结果显示相应的消息
    if (failedFiles.length === 0) {
      // 全部成功
      alert(`成功删除 ${successCount} 个文件！`)
    } else if (successCount === 0) {
      // 全部失败
      alert(`删除失败！所有 ${failedFiles.length} 个文件都无法删除。\n请检查文件权限或文件是否被占用。`)
    } else {
      // 部分成功部分失败
      alert(`删除完成：成功 ${successCount} 个，失败 ${failedFiles.length} 个。\n失败的文件：${failedFiles.slice(0, 3).join(', ')}${failedFiles.length > 3 ? '...' : ''}`)
    }
    
  } catch (error) {
    console.error('删除文件过程中出错:', error)
    alert('删除文件时出错，请查看控制台了解详情。')
  }
}

// 新增：计算每个重复组的可节省空间
const getGroupSavedSpace = (group: DuplicateGroup): number => {
  let totalSaved = 0
  const selectedFiles = group.files.filter(file => file.selected)
  if (selectedFiles.length > 1) {
    // 如果选择了多个文件，可以删除除第一个之外的所有文件
    // 第一个文件保留，其他文件的空间可以节省
    const filesToDelete = selectedFiles.slice(1)
    filesToDelete.forEach(file => {
      totalSaved += file.size
    })
  }
  return totalSaved
}

// 预览文件
const previewFile = (groupIndex: number, fileIndex: number) => {
  currentPreviewGroup.value = props.duplicateGroupsList[groupIndex]
  currentPreviewFileIndex.value = fileIndex
  showPreview.value = true
}

// 打开文件位置
const openFileLocation = async (filePath: string) => {
  try {
    console.log('打开文件位置:', filePath)
    await invoke('open_file_location', { filePath })
    console.log('成功打开文件位置')
  } catch (error) {
    console.error('打开文件位置失败:', error)
    alert(`打开文件位置失败: ${error}`)
  }
}

// 右键菜单相关状态
const contextMenu = ref({
  visible: false,
  x: 0,
  y: 0,
  target: null as { type: 'file' | 'group' | 'list', groupIndex?: number, fileIndex?: number } | null
})

// 显示文件右键菜单
const showFileContextMenu = (event: MouseEvent, groupIndex: number, fileIndex: number) => {
  event.preventDefault()
  event.stopPropagation() // 阻止事件冒泡
  
  // 注册到全局右键菜单系统
  const elementId = `file-${groupIndex}-${fileIndex}`
  registerContextMenu(elementId)
  
  contextMenu.value = {
    visible: true,
    x: event.clientX,
    y: event.clientY,
    target: { type: 'file', groupIndex, fileIndex }
  }
}

// 显示组右键菜单
const showGroupContextMenu = (event: MouseEvent, groupIndex: number) => {
  event.preventDefault()
  event.stopPropagation() // 阻止事件冒泡
  
  // 注册到全局右键菜单系统
  const elementId = `group-${groupIndex}`
  registerContextMenu(elementId)
  
  contextMenu.value = {
    visible: true,
    x: event.clientX,
    y: event.clientY,
    target: { type: 'group', groupIndex }
  }
}

// 显示列表右键菜单
const showListContextMenu = (event: MouseEvent) => {
  event.preventDefault()
  event.stopPropagation() // 阻止事件冒泡
  
  // 注册到全局右键菜单系统
  registerContextMenu('file-list')
  
  contextMenu.value = {
    visible: true,
    x: event.clientX,
    y: event.clientY,
    target: { type: 'list' }
  }
}

// 隐藏右键菜单
const hideContextMenu = () => {
  if (contextMenu.value.target) {
    // 根据目标类型注销全局注册
    const { type, groupIndex, fileIndex } = contextMenu.value.target
    
    switch (type) {
      case 'file':
        if (groupIndex !== undefined && fileIndex !== undefined) {
          unregisterContextMenu(`file-${groupIndex}-${fileIndex}`)
        }
        break
      case 'group':
        if (groupIndex !== undefined) {
          unregisterContextMenu(`group-${groupIndex}`)
        }
        break
      case 'list':
        unregisterContextMenu('file-list')
        break
    }
  }
  
  contextMenu.value.visible = false
}

// 移除局部右键菜单屏蔽逻辑，现在使用全局系统

// 处理右键菜单项点击
const handleContextMenuAction = (action: string) => {
  if (!contextMenu.value.target) return
  
  const { type, groupIndex, fileIndex } = contextMenu.value.target
  
  switch (action) {
    case 'select':
      if (type === 'file' && groupIndex !== undefined && fileIndex !== undefined) {
        props.duplicateGroupsList[groupIndex].files[fileIndex].selected = true
      } else if (type === 'group' && groupIndex !== undefined) {
        props.duplicateGroupsList[groupIndex].files.forEach(file => file.selected = true)
      }
      break
      
    case 'deselect':
      if (type === 'file' && groupIndex !== undefined && fileIndex !== undefined) {
        props.duplicateGroupsList[groupIndex].files[fileIndex].selected = false
      } else if (type === 'group' && groupIndex !== undefined) {
        props.duplicateGroupsList[groupIndex].files.forEach(file => file.selected = false)
      }
      break
      
    case 'preview':
      if (type === 'file' && groupIndex !== undefined && fileIndex !== undefined) {
        previewFile(groupIndex, fileIndex)
      }
      break
      
    case 'open_location':
      if (type === 'file' && groupIndex !== undefined && fileIndex !== undefined) {
        const file = props.duplicateGroupsList[groupIndex].files[fileIndex]
        openFileLocation(file.path)
      }
      break
      
    case 'delete':
      if (type === 'file' && groupIndex !== undefined && fileIndex !== undefined) {
        const file = props.duplicateGroupsList[groupIndex].files[fileIndex]
        if (confirm(`确定要删除文件 "${file.name}" 吗？`)) {
          deleteFilesFromContextMenu([file.path])
        }
      } else if (type === 'group' && groupIndex !== undefined) {
        const group = props.duplicateGroupsList[groupIndex]
        if (confirm(`确定要删除组 ${groupIndex + 1} 中的所有重复文件吗？`)) {
          const filePaths = group.files.map(f => f.path)
          deleteFilesFromContextMenu(filePaths)
        }
      }
      break
      
    case 'select_all':
      props.duplicateGroupsList.forEach(group => {
        group.files.forEach(file => file.selected = true)
      })
      break
      
    case 'deselect_all':
      props.duplicateGroupsList.forEach(group => {
        group.files.forEach(file => file.selected = false)
      })
      break
      
    case 'refresh':
      refreshResults()
      break
  }
  
  hideContextMenu()
}

// 删除指定的文件（用于右键菜单）
const deleteFilesFromContextMenu = async (filePaths: string[]) => {
  try {
    console.log('开始删除文件:', filePaths)
    
    let successCount = 0
    const failedFiles: string[] = []
    
    for (const filePath of filePaths) {
      try {
        const result = await invoke('delete_file', { filePath })
        console.log('删除文件成功:', filePath, result)
        successCount++
      } catch (error) {
        console.error('删除文件失败:', filePath, error)
        failedFiles.push(filePath)
      }
    }
    
    // 从重复组中移除已删除的文件
    const updatedGroups = props.duplicateGroupsList.map(group => {
      const remainingFiles = group.files.filter(file => {
        return !filePaths.includes(file.path) || failedFiles.includes(file.path)
      })
      return {
        ...group,
        files: remainingFiles
      }
    }).filter(group => group.files.length > 1)
    
    // 发出事件通知父组件更新数据
    emit('update-groups', updatedGroups)
    
    console.log('文件删除完成，剩余组数:', updatedGroups.length)
    
    // 根据删除结果显示相应的消息
    if (failedFiles.length === 0) {
      alert(`成功删除 ${successCount} 个文件！`)
    } else if (successCount === 0) {
      alert(`删除失败！所有 ${failedFiles.length} 个文件都无法删除。`)
    } else {
      alert(`删除完成：成功 ${successCount} 个，失败 ${failedFiles.length} 个。`)
    }
    
  } catch (error) {
    console.error('删除文件过程中出错:', error)
    alert('删除文件时出错，请查看控制台了解详情。')
  }
}

const closePreview = () => {
  showPreview.value = false
  currentPreviewGroup.value = undefined
  currentPreviewFileIndex.value = 0
}

const updateFileSelection = (fileIndex: number, selected: boolean) => {
  if (currentPreviewGroup.value) {
    currentPreviewGroup.value.files[fileIndex].selected = selected
  }
}

// 判断文件是否可预览
const isPreviewableFile = (fileName: string): boolean => {
  const lowerCaseFileName = fileName.toLowerCase()
  const ext = lowerCaseFileName.split('.').pop() || ''
  
  // 图片文件
  const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']
  if (imageExts.includes(ext)) return true
  
  // 视频文件
  const videoExts = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm', 'mkv']
  if (videoExts.includes(ext)) return true
  
  // 音频文件
  const audioExts = ['mp3', 'wav', 'flac', 'aac', 'ogg', 'wma']
  if (audioExts.includes(ext)) return true
  
  return false
}

// 手风琴折叠逻辑
const accordionOpen = ref({
  rules: true,
  text: false,
  location: false,
})

const toggleAccordion = (section: 'rules' | 'text' | 'location') => {
  Object.keys(accordionOpen.value).forEach(key => {
    accordionOpen.value[key as 'rules' | 'text' | 'location'] = false
  })
  accordionOpen.value[section] = true
}

// 新增：导航到文件
const navigateToFile = (fileIndex: number) => {
  if (currentPreviewGroup.value) {
    currentPreviewFileIndex.value = fileIndex
  }
}

// 排序函数
const applySorting = () => {
  console.log('应用排序:', sortOption.value, sortDirection.value)
  
  let sorted = [...props.duplicateGroupsList]
  
  switch (sortOption.value) {
    case 'groupSize':
      sorted.sort((a, b) => {
        const diff = a.files.length - b.files.length
        return sortDirection.value === 'asc' ? diff : -diff
      })
      break
      
    case 'fileSize':
      sorted.sort((a, b) => {
        const diff = a.size - b.size
        return sortDirection.value === 'asc' ? diff : -diff
      })
      break
      
    case 'fileName':
      sorted.sort((a, b) => {
        const aName = a.files[0]?.name || ''
        const bName = b.files[0]?.name || ''
        const diff = aName.localeCompare(bName)
        return sortDirection.value === 'asc' ? diff : -diff
      })
      break
      
    case 'filePath':
      sorted.sort((a, b) => {
        const aPath = a.files[0]?.path || ''
        const bPath = b.files[0]?.path || ''
        const diff = aPath.localeCompare(bPath)
        return sortDirection.value === 'asc' ? diff : -diff
      })
      break
      
    case 'modifiedDate':
      sorted.sort((a, b) => {
        const aDate = a.files[0]?.modified || new Date(0)
        const bDate = b.files[0]?.modified || new Date(0)
        const diff = aDate.getTime() - bDate.getTime()
        return sortDirection.value === 'asc' ? diff : -diff
      })
      break
      
    case 'savedSpace':
      sorted.sort((a, b) => {
        const aSaved = getGroupSavedSpace(a)
        const bSaved = getGroupSavedSpace(b)
        const diff = aSaved - bSaved
        return sortDirection.value === 'asc' ? diff : -diff
      })
      break
      
    default:
      // 默认顺序，不排序
      break
  }
  
  sortedGroups.value = sorted
}

// 切换排序方向
const toggleSortDirection = () => {
  sortDirection.value = sortDirection.value === 'asc' ? 'desc' : 'asc'
  applySorting()
}

// 新增：刷新扫描结果，清除已删除的文件
const refreshResults = async () => {
  console.log('开始刷新扫描结果...')
  
  try {
    // 验证所有文件是否存在
    const updatedGroups = []
    
    for (const group of props.duplicateGroupsList) {
      const validFiles = []
      
      for (const file of group.files) {
        try {
          const exists = await invoke('verify_file_exists', { filePath: file.path })
          if (exists) {
            validFiles.push(file)
          } else {
            console.log('文件不存在，已移除:', file.path)
          }
        } catch (error) {
          console.error('验证文件存在性失败:', file.path, error)
          // 如果验证失败，保留文件（可能是权限问题）
          validFiles.push(file)
        }
      }
      
      // 只有当文件数量大于1时才保留（重复文件组）
      if (validFiles.length > 1) {
        updatedGroups.push({
          ...group,
          files: validFiles
        })
      } else if (validFiles.length === 1) {
        console.log('组中只剩一个文件，已移除:', validFiles[0].path)
      }
    }
    
    // 发出事件通知父组件更新数据
    emit('update-groups', updatedGroups)
    
    const removedCount = props.duplicateGroupsList.reduce((total, group) => 
      total + group.files.length, 0) - updatedGroups.reduce((total, group) => 
      total + group.files.length, 0)
    
    if (removedCount > 0) {
      alert(`刷新完成！已移除 ${removedCount} 个不存在的文件。`)
    } else {
      alert('刷新完成！所有文件都存在。')
    }
    
  } catch (error) {
    console.error('刷新扫描结果失败:', error)
    alert('刷新失败，请查看控制台了解详情。')
  }
}

// 新增：应用保留规则
const applyRetentionRules = (data: { rules: any[], keepSelectedMarks: boolean }) => {
  console.log('应用保留规则:', data)
  
  const { rules } = data
  
  // 创建新的数组来触发响应式更新
  const updatedGroups = props.duplicateGroupsList.map(group => ({
    ...group,
    files: group.files.map(file => ({ ...file }))
  }))
  
  // 根据规则更新文件的selected属性
  rules.forEach(rule => {
    if (rule.criterion === 'max_file_size') {
      // 保留每组中最大的文件
      updatedGroups.forEach(group => {
        const maxSizeFile = group.files.reduce((max, file) => 
          file.size > max.size ? file : max
        )
        group.files.forEach(file => {
          file.selected = (file === maxSizeFile)
        })
      })
    } else if (rule.criterion === 'min_file_size') {
      // 保留每组中最小的文件
      updatedGroups.forEach(group => {
        const minSizeFile = group.files.reduce((min, file) => 
          file.size < min.size ? file : min
        )
        group.files.forEach(file => {
          file.selected = (file === minSizeFile)
        })
      })
    } else if (rule.criterion === 'max_resolution') {
      // 保留每组中分辨率最大的文件
      updatedGroups.forEach(group => {
        const maxResFile = group.files.reduce((max, file) => {
          const maxRes = getImageResolution(file.path) || 0
          const currentRes = getImageResolution(file.path) || 0
          return currentRes > maxRes ? file : max
        })
        group.files.forEach(file => {
          file.selected = (file === maxResFile)
        })
      })
    } else if (rule.criterion === 'min_resolution') {
      // 保留每组中分辨率最小的文件
      updatedGroups.forEach(group => {
        const minResFile = group.files.reduce((min, file) => {
          const minRes = getImageResolution(file.path) || 0
          const currentRes = getImageResolution(file.path) || 0
          return currentRes < minRes ? file : min
        })
        group.files.forEach(file => {
          file.selected = (file === minResFile)
        })
      })
    } else if (rule.criterion === 'earliest_modified') {
      // 保留每组中修改日期最早的文件
      updatedGroups.forEach(group => {
        const earliestFile = group.files.reduce((earliest, file) => 
          file.modified < earliest.modified ? file : earliest
        )
        group.files.forEach(file => {
          file.selected = (file === earliestFile)
        })
      })
    } else if (rule.criterion === 'earliest_created') {
      // 保留每组中修改日期最早的文件（因为没有created属性，使用modified）
      updatedGroups.forEach(group => {
        const earliestFile = group.files.reduce((earliest, file) => 
          file.modified < earliest.modified ? file : earliest
        )
        group.files.forEach(file => {
          file.selected = (file === earliestFile)
        })
      })
    } else if (rule.criterion === 'smallest_file') {
      // 保留每组中最小的文件
      updatedGroups.forEach(group => {
        const smallestFile = group.files.reduce((smallest, file) => 
          file.size < smallest.size ? file : smallest
        )
        group.files.forEach(file => {
          file.selected = (file === smallestFile)
        })
      })
    } else if (rule.criterion === 'longest_filename') {
      // 保留每组中文件名最长的文件
      updatedGroups.forEach(group => {
        const longestFile = group.files.reduce((longest, file) => 
          file.name.length > longest.name.length ? file : longest
        )
        group.files.forEach(file => {
          file.selected = (file === longestFile)
        })
      })
    } else if (rule.criterion === 'longest_path') {
      // 保留每组中路径最长的文件
      updatedGroups.forEach(group => {
        const longestFile = group.files.reduce((longest, file) => 
          file.path.length > longest.path.length ? file : longest
        )
        group.files.forEach(file => {
          file.selected = (file === longestFile)
        })
      })
    } else if (rule.criterion === 'filename_asc') {
      // 保留每组中文件名按字母顺序排第一的文件
      updatedGroups.forEach(group => {
        const firstFile = group.files.reduce((first, file) => {
          if (!first.name) return file
          if (!file.name) return first
          return file.name.localeCompare(first.name) < 0 ? file : first
        })
        group.files.forEach(file => {
          file.selected = (file === firstFile)
        })
      })
    } else if (rule.criterion === 'filename_contains') {
      // 保留每组中包含指定文本的文件
      if (rule.pattern) {
        updatedGroups.forEach(group => {
          const matchingFiles = group.files.filter(file => 
            file.name.toLowerCase().includes(rule.pattern.toLowerCase())
          )
          if (matchingFiles.length > 0) {
            // 如果有匹配的文件，选择第一个
            group.files.forEach(file => {
              file.selected = (file === matchingFiles[0])
            })
          }
        })
      }
    }
  })
  
  // 强制触发响应式更新 - 通过emit事件通知父组件
  console.log('更新后的组:', updatedGroups)
  console.log('规则应用完成，文件选择状态已更新')
  
  // 发出事件通知父组件更新数据
  emit('update-groups', updatedGroups)
}

// 辅助函数：获取图片分辨率
const getImageResolution = (_filePath: string): number => {
  // 这里应该实现获取图片分辨率的逻辑
  // 暂时返回0，实际应该从文件元数据中获取
  return 0
}



// 取消所有标记
const unmarkAll = () => {
  console.log('取消所有标记')
  
  // 创建新的数组来触发响应式更新
  const updatedGroups = props.duplicateGroupsList.map(group => ({
    ...group,
    files: group.files.map(file => ({ ...file, selected: false }))
  }))
  
  // 发出事件通知父组件更新数据
  emit('update-groups', updatedGroups)
  console.log('所有标记已取消')
}

// 反选所有标记
const invertAllMarks = () => {
  console.log('反选所有标记')
  
  // 创建新的数组来触发响应式更新
  const updatedGroups = props.duplicateGroupsList.map(group => ({
    ...group,
    files: group.files.map(file => ({ ...file, selected: !file.selected }))
  }))
  
  // 发出事件通知父组件更新数据
  emit('update-groups', updatedGroups)
  console.log('所有标记已反选')
}

// 处理文本模式标记
const handleTextModeMarking = (data: {
  includeSubfolders: boolean
  filenamePattern: string
  filenameMatchType: string
  pathPattern: string
  pathMatchType: string
  action: 'mark' | 'unmark'
}) => {
  console.log('处理文本模式标记:', data)
  console.log('文件名模式:', data.filenamePattern, '类型:', data.filenameMatchType)
  console.log('路径模式:', data.pathPattern, '类型:', data.pathMatchType)
  
  let totalMatched = 0
  
  // 根据文本模式选择文件
  props.duplicateGroupsList.forEach(group => {
    group.files.forEach(file => {
      let shouldProcess = false
      
      // 如果同时有文件名模式和路径模式，需要两者都匹配
      if (data.filenamePattern && data.filenamePattern.trim() && data.pathPattern && data.pathPattern.trim()) {
        // 检查文件名模式
        const fileName = file.name.toLowerCase()
        const filenamePattern = data.filenamePattern.toLowerCase()
        let filenameMatch = false
        
        switch (data.filenameMatchType) {
          case 'contains':
            filenameMatch = fileName.includes(filenamePattern)
            break
          case 'starts_with':
            filenameMatch = fileName.startsWith(filenamePattern)
            break
          case 'ends_with':
            filenameMatch = fileName.endsWith(filenamePattern)
            break
          case 'regex':
            try {
              const regex = new RegExp(filenamePattern, 'i')
              filenameMatch = regex.test(fileName)
            } catch (e) {
              console.warn('正则表达式无效:', filenamePattern)
            }
            break
        }
        
        // 检查路径模式
        const fileDir = file.path.substring(0, file.path.lastIndexOf('\\')).toLowerCase()
        const pathPattern = data.pathPattern.toLowerCase()
        let pathMatch = false
        
        switch (data.pathMatchType) {
          case 'contains':
            pathMatch = fileDir.includes(pathPattern)
            break
          case 'starts_with':
            pathMatch = fileDir.startsWith(pathPattern)
            break
          case 'ends_with':
            pathMatch = fileDir.endsWith(pathPattern)
            break
          case 'regex':
            try {
              const regex = new RegExp(pathPattern, 'i')
              pathMatch = regex.test(fileDir)
            } catch (e) {
              console.warn('正则表达式无效:', pathPattern)
            }
            break
        }
        
        // 需要同时满足文件名和路径条件
        shouldProcess = filenameMatch && pathMatch
        
        if (shouldProcess) {
          console.log('双重匹配:', file.name, '文件名模式:', filenamePattern, '路径模式:', pathPattern)
        }
      } else {
        // 只有文件名模式
        if (data.filenamePattern && data.filenamePattern.trim()) {
          const fileName = file.name.toLowerCase()
          const pattern = data.filenamePattern.toLowerCase()
          
          switch (data.filenameMatchType) {
            case 'contains':
              shouldProcess = fileName.includes(pattern)
              break
            case 'starts_with':
              shouldProcess = fileName.startsWith(pattern)
              break
            case 'ends_with':
              shouldProcess = fileName.endsWith(pattern)
              break
            case 'regex':
              try {
                const regex = new RegExp(pattern, 'i')
                shouldProcess = regex.test(fileName)
              } catch (e) {
                console.warn('正则表达式无效:', pattern)
              }
              break
          }
          
          if (shouldProcess) {
            console.log('文件名匹配:', file.name, '模式:', pattern, '类型:', data.filenameMatchType)
          }
        }
        
        // 只有路径模式
        if (data.pathPattern && data.pathPattern.trim()) {
          // 获取文件的目录路径（不包含文件名）
          const fileDir = file.path.substring(0, file.path.lastIndexOf('\\')).toLowerCase()
          const pattern = data.pathPattern.toLowerCase()
          
          let pathMatch = false
          switch (data.pathMatchType) {
            case 'contains':
              pathMatch = fileDir.includes(pattern)
              break
            case 'starts_with':
              pathMatch = fileDir.startsWith(pattern)
              break
            case 'ends_with':
              pathMatch = fileDir.endsWith(pattern)
              break
            case 'regex':
              try {
                const regex = new RegExp(pattern, 'i')
                pathMatch = regex.test(fileDir)
              } catch (e) {
                console.warn('正则表达式无效:', pattern)
              }
              break
          }
          
          if (pathMatch) {
            shouldProcess = true
            console.log('路径匹配:', file.path, '目录:', fileDir, '模式:', pattern, '类型:', data.pathMatchType)
          }
        }
      }
      
      if (shouldProcess) {
        if (data.action === 'mark') {
          file.selected = true
        } else {
          file.selected = false
        }
        totalMatched++
      }
    })
  })
  
  const actionText = data.action === 'mark' ? '标记' : '取消标记'
  console.log(`文本模式${actionText}已应用，共处理 ${totalMatched} 个文件`)
  
  // 发出事件通知父组件更新数据
  emit('update-groups', props.duplicateGroupsList)
}

// 缩略图网格事件处理
const handleThumbnailFileSelect = (groupIndex: number, fileIndex: number, selected: boolean) => {
  const group = props.duplicateGroupsList[groupIndex]
  if (group && group.files[fileIndex]) {
    group.files[fileIndex].selected = selected
  }
}

const updateThumbnailGroups = (updatedGroups: any[]) => {
  // 更新组数据
  const newGroups = updatedGroups.map((group, index) => ({
    ...props.duplicateGroupsList[index],
    files: group.files
  }))
  emit('update-groups', newGroups)
}

// 聚类视图事件处理
const handleClusterUpdate = (updatedGroups: DuplicateGroup[]) => {
  emit('update-groups', updatedGroups)
}

// 处理目录位置标记
const handleLocationMarking = (data: {
  folderName: string
  markOtherDirectories: boolean
  invertCurrentFolder: boolean
  markCurrentFolder: boolean
  invertOtherLocations: boolean
  action: 'other' | 'current'
}) => {
  console.log('处理目录位置标记:', data)
  
  if (!data.folderName || !data.folderName.trim()) {
    console.warn('文件夹名称不能为空')
    return
  }
  
  const folderPattern = data.folderName.toLowerCase()
  let totalMarked = 0
  let totalInverted = 0
  
  props.duplicateGroupsList.forEach(group => {
    group.files.forEach(file => {
      const filePath = file.path.toLowerCase()
      const isInTargetFolder = filePath.includes(folderPattern)
      
      if (data.action === 'other') {
        // 处理"标记其它目录中所有与此目录重复的文件"
        if (data.markOtherDirectories && !isInTargetFolder) {
          file.selected = true
          totalMarked++
          console.log('标记其他目录文件:', file.name, file.path)
        }
        
        // 处理"且反选(取消选中)该文件夹中的文件"
        if (data.invertCurrentFolder && isInTargetFolder) {
          file.selected = false
          totalInverted++
          console.log('反选目标文件夹文件:', file.name, file.path)
        }
      } else if (data.action === 'current') {
        // 处理"标记所有此文件夹中与其他位置相同的项目"
        if (data.markCurrentFolder && isInTargetFolder) {
          file.selected = true
          totalMarked++
          console.log('标记目标文件夹文件:', file.name, file.path)
        }
        
        // 处理"且反选(取消选中)其他位置的文件"
        if (data.invertOtherLocations && !isInTargetFolder) {
          file.selected = false
          totalInverted++
          console.log('反选其他位置文件:', file.name, file.path)
        }
      }
    })
  })
  
  const actionText = data.action === 'other' ? '其他目录' : '当前文件夹'
  console.log(`目录位置标记已应用 (${actionText})，标记 ${totalMarked} 个文件，反选 ${totalInverted} 个文件`)
  
  // 发出事件通知父组件更新数据
  emit('update-groups', props.duplicateGroupsList)
}

// 生成缩略图
const generateThumbnail = async (file: FileInfo) => {
  if (file.thumbnailData || file.thumbnailLoading || file.thumbnailError) {
    return
  }
  
  file.thumbnailLoading = true
  
  try {
    const thumbnailInfo = await invoke<{
      data: string
      width: number
      height: number
      size: number
    }>('generate_thumbnail', { filePath: file.path })
    
    file.thumbnailData = thumbnailInfo.data
    file.thumbnailLoading = false
    
    console.log(`缩略图生成成功: ${file.name}, 大小: ${thumbnailInfo.size} 字节`)
    
  } catch (error) {
    console.error(`缩略图生成失败: ${file.name}`, error)
    file.thumbnailError = true
    file.thumbnailLoading = false
  }
}

// 批量生成可见文件的缩略图
const generateVisibleThumbnails = async () => {
  const visibleFiles: FileInfo[] = []
  
  // 收集当前可见的文件（前20个文件）
  props.duplicateGroupsList.slice(0, 10).forEach(group => {
    group.files.slice(0, 2).forEach(file => {
      if (isPreviewableFile(file.name)) {
        visibleFiles.push(file)
      }
    })
  })
  
  // 限制并发数量
  const batchSize = 3
  for (let i = 0; i < visibleFiles.length; i += batchSize) {
    const batch = visibleFiles.slice(i, i + batchSize)
    await Promise.allSettled(batch.map(file => generateThumbnail(file)))
  }
}

// 处理缩略图错误
const handleThumbnailError = (file: FileInfo) => {
  file.thumbnailError = true
  file.thumbnailLoading = false
}

// 页面加载时初始化
onMounted(() => {
  if (props.duplicateGroupsList.length > 0) {
    console.log('页面加载完成，文件数量:', props.duplicateGroupsList.length)
    console.log('当前文件选择状态:', props.duplicateGroupsList.map(group => 
      group.files.map(file => ({ name: file.name, selected: file.selected }))
    ))
    
    // 初始化排序
    applySorting()
    
    // 生成缩略图
    nextTick(() => {
      generateVisibleThumbnails()
    })
  }
  
  // 添加局部事件监听器（右键菜单现在由全局系统管理）
  document.addEventListener('click', hideContextMenu)
  document.addEventListener('scroll', hideContextMenu)
})

// 组件卸载时清理事件监听器
onUnmounted(() => {
  document.removeEventListener('click', hideContextMenu)
  document.removeEventListener('scroll', hideContextMenu)
})

// 监听数据变化，自动重新应用排序
watch(() => props.duplicateGroupsList, () => {
  if (props.duplicateGroupsList.length > 0) {
    applySorting()
  }
}, { deep: true })
</script>

<style scoped>
/* 鼠标悬停效果优化 */
.hover\:bg-gray-100:hover {
  background-color: #f3f4f6;
}

/* 按钮悬停效果 */
.hover\:scale-105:hover {
  transform: scale(1.05);
}

/* 过渡动画 */
.transition-all {
  transition: all 0.2s ease-in-out;
}

.transition-colors {
  transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
}
</style>
